﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using Common;

namespace ThreeItems
{
    public partial class MainForm : Form
    {

        #region 算法参数 和 变量
        private BackgroundWorker bgWorker;
        private double linearSearchStep = 1; //一维搜索的固定步长，用于找牛拉算法的初始步长
        private int repeatTimes = 10;
        private bool showGraph;
        private double stepError = 0.00001; //牛拉算法找到的序列，最小收敛误差(最后两个元素之差的绝对值)
        //误差接受上限
        private double tolerences = 0.01;
        CentralizedAlg centralizedAlg = new CentralizedAlg();
        DecentralizedAlg decentralizedAlg = new DecentralizedAlg();
        #endregion

        public MainForm()
        {
            InitializeComponent();
        }

        //点击开始按钮
        private void btnStart_Click(object sender, EventArgs e)
        {

            tolerences = Convert.ToDouble(tbxTolerence.Text);
            repeatTimes = Convert.ToInt32(tbxRepeatTimes.Text);
            linearSearchStep = Convert.ToDouble(tbxLinearSrchStep.Text);
            stepError = Convert.ToDouble(tbxStepError.Text);

            //循环取出来数据进行计算,后台线程去跑这个程序
            bgWorker = new BackgroundWorker();
            bgWorker.DoWork += DoWork;
            bgWorker.ProgressChanged += ShowProgress;
            bgWorker.RunWorkerCompleted += WorkCompleted;
            bgWorker.WorkerReportsProgress = true;
            bgWorker.WorkerSupportsCancellation = true;

            bgWorker.RunWorkerAsync();


            btnStart.Enabled = false;
            tbxIdStart.Enabled = false;
            tbxIdEnd.Enabled = false;
            tbxLinearSrchStep.Enabled = false;
            tbxRepeatTimes.Enabled = false;
            tbxStepError.Enabled = false;
            tbxTolerence.Enabled = false;
        }

        //开始计算
        private void DoWork(object sender, DoWorkEventArgs e)
        {
            int start = Convert.ToInt32(tbxIdStart.Text);
            int end = Convert.ToInt32(tbxIdEnd.Text);

            //设置算法参数
            SetupParameters();

            for (int i = start; i <= end; i++)
            {
                bgWorker.ReportProgress((100 * (i - start)) / (end - start + 1), i);

                ExampleInfo example = DataGateWay.Get(i);

                centralizedAlg.RunComputing(example);
                //更新数据库
                DataGateWay.UpdateCentralizedModel(example);

                decentralizedAlg.RunComputing(example);
                //更新数据库
                DataGateWay.UpdateDecentralizedModel(example);
            }
        }


        private void SetupParameters()
        {
            centralizedAlg.Tolerences = Convert.ToDouble(tbxTolerence.Text);
            centralizedAlg.RepeatTimes = Convert.ToInt32(tbxRepeatTimes.Text);
            centralizedAlg.LinearSearchStep = Convert.ToDouble(tbxLinearSrchStep.Text);
            centralizedAlg.StepError = Convert.ToDouble(tbxStepError.Text);

            if (rbtnPriciseProfit.Checked)
                centralizedAlg.ProfitMethod = ProfitType.Pricise;
            else
                centralizedAlg.ProfitMethod = ProfitType.Approximation;

            if (rbtnPriciseGradient.Checked)
                centralizedAlg.GradientMethod = GradientType.Pricise;
            else
                centralizedAlg.GradientMethod = GradientType.Approximation;

            if (rbtnPowell.Checked)
                centralizedAlg.StepLengthMethod = StepLengthType.PowellCondition;
            else if (rbtnGoldenSection.Checked)
                centralizedAlg.StepLengthMethod = StepLengthType.GoldenSection;

            decentralizedAlg.MaxIteration = Convert.ToInt32(tbxMaxIteration.Text);

            decentralizedAlg.Tolerences = Convert.ToDouble(tbxTolerence.Text);
            decentralizedAlg.RepeatTimes = Convert.ToInt32(tbxRepeatTimes.Text);
        }

        #region 后台线程相关方法

        private void WorkCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btnStart.Enabled = true;
            tbxIdStart.Enabled = true;
            tbxIdEnd.Enabled = true;
            tbxLinearSrchStep.Enabled = true;
            tbxRepeatTimes.Enabled = true;
            tbxStepError.Enabled = true;
            tbxTolerence.Enabled = true;

            MessageBox.Show("Job is done!!");
        }

        private void ShowProgress(object sender, ProgressChangedEventArgs e)
        {
            lblPercentage.Text = e.ProgressPercentage + " %";

            lblCurrent.Text = string.Format("{0}/{1}", e.UserState, 10000);

            progressBar1.Value = e.ProgressPercentage;
        }

        #endregion

        private void button1_Click(object sender, EventArgs e)
        {
            BackgroundWorker worker = new BackgroundWorker();
            worker.DoWork += TestWork;
            worker.RunWorkerAsync();

        }
        private void TestWork(object sender, DoWorkEventArgs e)
        {
            DecentralizedGridSearchAlg gs = new DecentralizedGridSearchAlg();

            int start = Convert.ToInt32(tbxIdStart.Text);
            int end = Convert.ToInt32(tbxIdEnd.Text);

            for (int i = start; i <= end; i++)
            {
                ExampleInfo example = DataGateWay.Get(i);

                gs.RunComputing(example);

                Trace.WriteLine("第" + i + "个算例计算完成");
            }
        }
    }
}